package com.zdp.contentcenter.sentinel.test;

import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author sesshomaru
 * @date 2020/9/22 17:27
 *
 * 重新定义资源名称
 *
 * 把  /shares/1 和 /shares/2 统一改成/shares/{number}
 * 在sentinel中只需配置一次规则就可以对这两个url进行监控
 * 此时只需在sentinel控制台配置 /shares/{number} 这个路径的规则就可以控制 /share/* 的不同的url
 * 如 /shares/1 , /shares/2 , /shares/3 , /shares/4 ...... 都监控起来
 */
@Component
@Slf4j
public class MyUrlCleaner implements UrlCleaner {
    @Override
    public String clean(String originUrl) {
        // 访问 http://localhost:8010/shares/1 和 http://localhost:8010/shares/2
        // 下方会打印  /shares/1 和 /shares/2 但是在sentinel中是分开显示的，这就很麻烦相同路径规则需要配置两次
        // 可以通过这个方法把  /shares/1 和 /shares/2 统一改成/shares/{number}
        log.info("originUrl = {}",originUrl);
        // 数组: shares，1  或着 shares，2  那么把 1和 2 用{number}替换就可以了
        String[] split = originUrl.split("/");
        // 返回 /shares/{number}
        return  Arrays.stream(split)
                .map(string -> {
                    // 如果是数值类型就用{number}替换
                    if (NumberUtils.isNumber(string)) {
                        // 1，2 请求参数用{number}替换
                        return "{number}";
                    }
                    // 如果不是则返回它本身也就是 shares
                    return string;
                })
                // a就是shares b就是{number} 然后拼接一下
                .reduce((a,b) -> a + "/" + b)
                // 结果就是 /shares/{number}
                // 如果split是一个空数组 就返回""空字符串
                .orElse("");

    }
}
